﻿using System;
using System.Collections.Generic;
using Microsoft.Xna.Framework.Content;
using System.Linq;
using System.Text;
using Microsoft.Xna.Framework.Content.Pipeline;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Content.Pipeline.Serialization.Compiler;

using Input;

namespace GUILibrary 
{
    public class GUIScreenManager : MouseInputListener
    {
        /// <summary>
        /// Screen name to xml file name
        /// </summary>
        private Dictionary<string, string> screenNames;

        /// <summary>
        /// Screen name to GUIScreen object
        /// </summary>
        private Dictionary<string, GUIScreen> guiScreens;

        private List<ActionListener> actionListeners;
        private string currentGUIScreen;
        private string currentAction;

        private string startingScreen;

        private SpriteBatch spriteBatch;

        public GUIScreenManager()
        {
            screenNames = new Dictionary<string, string>();
            guiScreens = new Dictionary<string, GUIScreen>();
            actionListeners = new List<ActionListener>();
        }

        public void Initialize(GraphicsDevice graphics)
        {
            spriteBatch = new SpriteBatch(graphics);
            currentGUIScreen = StartingScreen;
        }

        public string StartingScreen
        {
            get { return startingScreen; }
            set { startingScreen = value; }
        }

        [ContentSerializerIgnore]
        public Dictionary<string, GUIScreen> GUIScreens
        {
            get { return guiScreens; }
        }

        public Dictionary<string, string> ScreenNames
        {
            get { return screenNames; }
            set { screenNames = value; }
        }

        public void Load(ContentManager cm)
        {
            foreach (string state in screenNames.Keys)
            {
                guiScreens.Add(state, cm.Load<GUIScreen>("GUI/" + screenNames[state]));
                guiScreens[state].RegisterComponents(cm);
                guiScreens[state].RegisterToManager(this);
            }
        }

        public void UpdateMouseInput(GameInput Input)
        {
            guiScreens[currentGUIScreen].UpdateHover(Input.GetMousePosition());
            guiScreens[currentGUIScreen].UpdateMouseClick(Input);
            if (Input.IsLeftMouseButtonPressed())
                currentAction = guiScreens[currentGUIScreen].GetAction();
            else
                currentAction = null;

            currentAction = guiScreens[currentGUIScreen].GetComponentAction();
        }

        public void OnMouseRegister(GameInput Input)
        {
            //do nothing
        }

        public void Draw()
        {
            spriteBatch.Begin();

            guiScreens[currentGUIScreen].Draw(spriteBatch);

            spriteBatch.End();
        }

        /// <summary>
        /// Switch to the GUIScreen specified by the name.  If
        /// the GUIScreen doesn't exist, don't switch.
        /// </summary>
        /// <param name="name"></param>
        public void SwitchScreen(string name)
        {
            if (GUIScreens.ContainsKey(name))
                currentGUIScreen = name;
        }

        public void Update()
        {
            if(currentAction!=null)
            {
                if (guiScreens.ContainsKey(currentAction))
                {
                    currentGUIScreen = currentAction; //NOTE: Will this cause an issue because it occurs before ActionListeners are updated?
                }

                foreach(ActionListener AL in actionListeners)
                {
                    AL.UpdateAction(currentAction);
                }
            }
        }

        public void AddActionListener(ActionListener newAL)
        {
            actionListeners.Add(newAL);
        }
    }

    public class GUIScreenManagerContentReader : ContentTypeReader<GUIScreenManager>
    {
        protected override GUIScreenManager Read(ContentReader input, GUIScreenManager existingInstance)
        {
            GUIScreenManager guiScreenManager = new GUIScreenManager();
            guiScreenManager.StartingScreen = input.ReadString();
            guiScreenManager.ScreenNames = input.ReadObject<Dictionary<string, string>>();

            guiScreenManager.Load(input.ContentManager);

            return guiScreenManager;
        }
    }
}
